home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / Musique / Quod Libet / quodlibet-3.3.0-installer.exe / bin / csv.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2014-12-31  |  13KB  |  436 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.7)
  3.  
  4. '''
  5. csv.py - read/write/investigate CSV files
  6. '''
  7. import re
  8. from functools import reduce
  9. from _csv import Error, __version__, writer, reader, register_dialect, unregister_dialect, get_dialect, list_dialects, field_size_limit, QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE, __doc__
  10. from _csv import Dialect as _Dialect
  11.  
  12. try:
  13.     from cStringIO import StringIO
  14. except ImportError:
  15.     from StringIO import StringIO
  16.  
  17. __all__ = [
  18.     'QUOTE_MINIMAL',
  19.     'QUOTE_ALL',
  20.     'QUOTE_NONNUMERIC',
  21.     'QUOTE_NONE',
  22.     'Error',
  23.     'Dialect',
  24.     '__doc__',
  25.     'excel',
  26.     'excel_tab',
  27.     'field_size_limit',
  28.     'reader',
  29.     'writer',
  30.     'register_dialect',
  31.     'get_dialect',
  32.     'list_dialects',
  33.     'Sniffer',
  34.     'unregister_dialect',
  35.     '__version__',
  36.     'DictReader',
  37.     'DictWriter']
  38.  
  39. class Dialect:
  40.     '''Describe an Excel dialect.
  41.  
  42.     This must be subclassed (see csv.excel).  Valid attributes are:
  43.     delimiter, quotechar, escapechar, doublequote, skipinitialspace,
  44.     lineterminator, quoting.
  45.  
  46.     '''
  47.     _name = ''
  48.     _valid = False
  49.     delimiter = None
  50.     quotechar = None
  51.     escapechar = None
  52.     doublequote = None
  53.     skipinitialspace = None
  54.     lineterminator = None
  55.     quoting = None
  56.     
  57.     def __init__(self):
  58.         if self.__class__ != Dialect:
  59.             self._valid = True
  60.         self._validate()
  61.  
  62.     
  63.     def _validate(self):
  64.         
  65.         try:
  66.             _Dialect(self)
  67.         except TypeError:
  68.             e = None
  69.             raise Error(str(e))
  70.  
  71.  
  72.  
  73.  
  74. class excel(Dialect):
  75.     '''Describe the usual properties of Excel-generated CSV files.'''
  76.     delimiter = ','
  77.     quotechar = '"'
  78.     doublequote = True
  79.     skipinitialspace = False
  80.     lineterminator = '\r\n'
  81.     quoting = QUOTE_MINIMAL
  82.  
  83. register_dialect('excel', excel)
  84.  
  85. class excel_tab(excel):
  86.     '''Describe the usual properties of Excel-generated TAB-delimited files.'''
  87.     delimiter = '\t'
  88.  
  89. register_dialect('excel-tab', excel_tab)
  90.  
  91. class DictReader:
  92.     
  93.     def __init__(self, f, fieldnames = None, restkey = None, restval = None, dialect = 'excel', *args, **kwds):
  94.         self._fieldnames = fieldnames
  95.         self.restkey = restkey
  96.         self.restval = restval
  97.         self.reader = reader(f, dialect, *args, **kwds)
  98.         self.dialect = dialect
  99.         self.line_num = 0
  100.  
  101.     
  102.     def __iter__(self):
  103.         return self
  104.  
  105.     
  106.     def fieldnames(self):
  107.         if self._fieldnames is None:
  108.             
  109.             try:
  110.                 self._fieldnames = self.reader.next()
  111.             except StopIteration:
  112.                 pass
  113.             
  114.  
  115.         self.line_num = self.reader.line_num
  116.         return self._fieldnames
  117.  
  118.     fieldnames = property(fieldnames)
  119.     
  120.     def fieldnames(self, value):
  121.         self._fieldnames = value
  122.  
  123.     fieldnames = fieldnames.setter(fieldnames)
  124.     
  125.     def next(self):
  126.         if self.line_num == 0:
  127.             self.fieldnames
  128.         row = self.reader.next()
  129.         self.line_num = self.reader.line_num
  130.         while row == []:
  131.             row = self.reader.next()
  132.         d = dict(zip(self.fieldnames, row))
  133.         lf = len(self.fieldnames)
  134.         lr = len(row)
  135.         if lf < lr:
  136.             d[self.restkey] = row[lf:]
  137.         elif lf > lr:
  138.             for key in self.fieldnames[lr:]:
  139.                 d[key] = self.restval
  140.             
  141.         return d
  142.  
  143.  
  144.  
  145. class DictWriter:
  146.     
  147.     def __init__(self, f, fieldnames, restval = '', extrasaction = 'raise', dialect = 'excel', *args, **kwds):
  148.         self.fieldnames = fieldnames
  149.         self.restval = restval
  150.         if extrasaction.lower() not in ('raise', 'ignore'):
  151.             raise ValueError, "extrasaction (%s) must be 'raise' or 'ignore'" % extrasaction
  152.         self.extrasaction = extrasaction
  153.         self.writer = writer(f, dialect, *args, **kwds)
  154.  
  155.     
  156.     def writeheader(self):
  157.         header = dict(zip(self.fieldnames, self.fieldnames))
  158.         self.writerow(header)
  159.  
  160.     
  161.     def _dict_to_list(self, rowdict):
  162.         if self.extrasaction == 'raise':
  163.             wrong_fields = [ k for k in rowdict if k not in self.fieldnames ]
  164.             if wrong_fields:
  165.                 raise ValueError('dict contains fields not in fieldnames: ' + ', '.join(wrong_fields))
  166.         return [ rowdict.get(key, self.restval) for key in self.fieldnames ]
  167.  
  168.     
  169.     def writerow(self, rowdict):
  170.         return self.writer.writerow(self._dict_to_list(rowdict))
  171.  
  172.     
  173.     def writerows(self, rowdicts):
  174.         rows = []
  175.         for rowdict in rowdicts:
  176.             rows.append(self._dict_to_list(rowdict))
  177.         
  178.         return self.writer.writerows(rows)
  179.  
  180.  
  181.  
  182. try:
  183.     complex
  184. except NameError:
  185.     complex = float
  186.  
  187.  
  188. class Sniffer:
  189.     '''
  190.     "Sniffs" the format of a CSV file (i.e. delimiter, quotechar)
  191.     Returns a Dialect object.
  192.     '''
  193.     
  194.     def __init__(self):
  195.         self.preferred = [
  196.             ',',
  197.             '\t',
  198.             ';',
  199.             ' ',
  200.             ':']
  201.  
  202.     
  203.     def sniff(self, sample, delimiters = None):
  204.         '''
  205.         Returns a dialect (or None) corresponding to the sample
  206.         '''
  207.         (quotechar, doublequote, delimiter, skipinitialspace) = self._guess_quote_and_delimiter(sample, delimiters)
  208.         if not delimiter:
  209.             (delimiter, skipinitialspace) = self._guess_delimiter(sample, delimiters)
  210.         if not delimiter:
  211.             raise Error, 'Could not determine delimiter'
  212.         
  213.         class dialect(Dialect):
  214.             _name = 'sniffed'
  215.             lineterminator = '\r\n'
  216.             quoting = QUOTE_MINIMAL
  217.  
  218.         dialect.doublequote = doublequote
  219.         dialect.delimiter = delimiter
  220.         if not quotechar:
  221.             pass
  222.         dialect.quotechar = '"'
  223.         dialect.skipinitialspace = skipinitialspace
  224.         return dialect
  225.  
  226.     
  227.     def _guess_quote_and_delimiter(self, data, delimiters):
  228.         """
  229.         Looks for text enclosed between two identical quotes
  230.         (the probable quotechar) which are preceded and followed
  231.         by the same character (the probable delimiter).
  232.         For example:
  233.                          ,'some text',
  234.         The quote with the most wins, same with the delimiter.
  235.         If there is no quotechar the delimiter can't be determined
  236.         this way.
  237.         """
  238.         matches = []
  239.         for restr in ('(?P<delim>[^\\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?P=delim)', '(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?P<delim>[^\\w\n"\'])(?P<space> ?)', '(?P<delim>>[^\\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?:$|\n)', '(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?:$|\n)'):
  240.             regexp = re.compile(restr, re.DOTALL | re.MULTILINE)
  241.             matches = regexp.findall(data)
  242.             if matches:
  243.                 break
  244.                 continue
  245.         if not matches:
  246.             return ('', False, None, 0)
  247.         quotes = None
  248.         delims = { }
  249.         spaces = 0
  250.         for m in matches:
  251.             n = regexp.groupindex['quote'] - 1
  252.             key = m[n]
  253.             if key:
  254.                 quotes[key] = quotes.get(key, 0) + 1
  255.             
  256.             try:
  257.                 n = regexp.groupindex['delim'] - 1
  258.                 key = m[n]
  259.             except KeyError:
  260.                 continue
  261.  
  262.             if key:
  263.                 if delimiters is None or key in delimiters:
  264.                     delims[key] = delims.get(key, 0) + 1
  265.             
  266.             try:
  267.                 n = regexp.groupindex['space'] - 1
  268.             except KeyError:
  269.                 continue
  270.  
  271.             if m[n]:
  272.                 spaces += 1
  273.                 continue
  274.         quotechar = reduce((lambda a, b, quotes = quotes: if not quotes[a] > quotes[b] or a:
  275. passb), quotes.keys())
  276.         if delims:
  277.             delim = reduce((lambda a, b, delims = delims: if not delims[a] > delims[b] or a:
  278. passb), delims.keys())
  279.             skipinitialspace = delims[delim] == spaces
  280.             if delim == '\n':
  281.                 delim = ''
  282.             
  283.         else:
  284.             delim = ''
  285.             skipinitialspace = 0
  286.         dq_regexp = re.compile('((%(delim)s)|^)\\W*%(quote)s[^%(delim)s\\n]*%(quote)s[^%(delim)s\\n]*%(quote)s\\W*((%(delim)s)|$)' % {
  287.             'delim': re.escape(delim),
  288.             'quote': quotechar }, re.MULTILINE)
  289.         if dq_regexp.search(data):
  290.             doublequote = True
  291.         else:
  292.             doublequote = False
  293.         return (quotechar, doublequote, delim, skipinitialspace)
  294.  
  295.     
  296.     def _guess_delimiter(self, data, delimiters):
  297.         """
  298.         The delimiter /should/ occur the same number of times on
  299.         each row. However, due to malformed data, it may not. We don't want
  300.         an all or nothing approach, so we allow for small variations in this
  301.         number.
  302.           1) build a table of the frequency of each character on every line.
  303.           2) build a table of frequencies of this frequency (meta-frequency?),
  304.              e.g.  'x occurred 5 times in 10 rows, 6 times in 1000 rows,
  305.              7 times in 2 rows'
  306.           3) use the mode of the meta-frequency to determine the /expected/
  307.              frequency for that character
  308.           4) find out how often the character actually meets that goal
  309.           5) the character that best meets its goal is the delimiter
  310.         For performance reasons, the data is evaluated in chunks, so it can
  311.         try and evaluate the smallest portion of the data possible, evaluating
  312.         additional chunks as necessary.
  313.         """
  314.         data = filter(None, data.split('\n'))
  315.         ascii = [ chr(c) for c in range(127) ]
  316.         chunkLength = min(10, len(data))
  317.         iteration = 0
  318.         charFrequency = { }
  319.         modes = { }
  320.         delims = { }
  321.         start = 0
  322.         end = min(chunkLength, len(data))
  323.         while start < len(data):
  324.             iteration += 1
  325.             for line in data[start:end]:
  326.                 for char in ascii:
  327.                     metaFrequency = charFrequency.get(char, { })
  328.                     freq = line.count(char)
  329.                     metaFrequency[freq] = metaFrequency.get(freq, 0) + 1
  330.                     charFrequency[char] = metaFrequency
  331.                 
  332.             
  333.             for char in charFrequency.keys():
  334.                 items = charFrequency[char].items()
  335.                 if len(items) == 1 and items[0][0] == 0:
  336.                     continue
  337.                 if len(items) > 1:
  338.                     modes[char] = reduce((lambda a, b: if not a[1] > b[1] or a:
  339. passb), items)
  340.                     items.remove(modes[char])
  341.                     modes[char] = (modes[char][0], modes[char][1] - reduce((lambda a, b: (0, a[1] + b[1])), items)[1])
  342.                     continue
  343.                 modes[char] = items[0]
  344.             
  345.             modeList = modes.items()
  346.             total = float(chunkLength * iteration)
  347.             consistency = 1
  348.             threshold = 0.9
  349.             while len(delims) == 0 and consistency >= threshold:
  350.                 for k, v in modeList:
  351.                     if v[0] > 0 and v[1] > 0 or v[1] / total >= consistency:
  352.                         if delimiters is None or k in delimiters:
  353.                             delims[k] = v
  354.                         
  355.                 
  356.                 consistency -= 0.01
  357.             if len(delims) == 1:
  358.                 delim = delims.keys()[0]
  359.                 skipinitialspace = data[0].count(delim) == data[0].count('%c ' % delim)
  360.                 return (delim, skipinitialspace)
  361.             start = None
  362.             end += chunkLength
  363.         if not delims:
  364.             return ('', 0)
  365.         if None(delims) > 1:
  366.             for d in self.preferred:
  367.                 if d in delims.keys():
  368.                     skipinitialspace = data[0].count(d) == data[0].count('%c ' % d)
  369.                     return (d, skipinitialspace)
  370.             
  371.         items = [ (v, k) for k, v in delims.items() ]
  372.         items.sort()
  373.         delim = items[-1][1]
  374.         skipinitialspace = data[0].count(delim) == data[0].count('%c ' % delim)
  375.         return (delim, skipinitialspace)
  376.  
  377.     
  378.     def has_header(self, sample):
  379.         rdr = reader(StringIO(sample), self.sniff(sample))
  380.         header = rdr.next()
  381.         columns = len(header)
  382.         columnTypes = { }
  383.         for i in range(columns):
  384.             columnTypes[i] = None
  385.         
  386.         checked = 0
  387.         for row in rdr:
  388.             if checked > 20:
  389.                 break
  390.             checked += 1
  391.             if len(row) != columns:
  392.                 continue
  393.             for col in columnTypes.keys():
  394.                 for thisType in [
  395.                     int,
  396.                     long,
  397.                     float,
  398.                     complex]:
  399.                     
  400.                     try:
  401.                         thisType(row[col])
  402.                     continue
  403.                     except (ValueError, OverflowError):
  404.                         continue
  405.                     
  406.  
  407.                 else:
  408.                     thisType = len(row[col])
  409.                 if thisType == long:
  410.                     thisType = int
  411.                 if thisType != columnTypes[col] or columnTypes[col] is None:
  412.                     columnTypes[col] = thisType
  413.                 else:
  414.                     del columnTypes[col]
  415.             
  416.         
  417.         hasHeader = 0
  418.         for col, colType in columnTypes.items():
  419.             if type(colType) == type(0):
  420.                 if len(header[col]) != colType:
  421.                     hasHeader += 1
  422.                 else:
  423.                     hasHeader -= 1
  424.             
  425.             try:
  426.                 colType(header[col])
  427.             except (ValueError, TypeError):
  428.                 hasHeader += 1
  429.                 continue
  430.  
  431.             hasHeader -= 1
  432.         
  433.         return hasHeader > 0
  434.  
  435.  
  436.